from datetime import *
import Core.Gadget as Gadget
import Core.WindFunctions as Wind


# 处理新股票
def ProcessNewStock(database, symbols, datetime1):
    # ---Get Names---
    # names = w.wss(instruments, "sec_name")

    sDatetime = datetime1.strftime('%Y%m%d')

    # ---Get Industries---
    # 申万行业
    params = {"industryType": 1, "industryStandard": 1, "tradeDate": datetime1}
    fields = "industry2"
    #
    swIndustries1 = Wind.WSS(symbols, fields, params)
    params["industryStandard"] = 2
    swIndustries2 = Wind.WSS(symbols, fields, params)
    params["industryStandard"] = 3
    swIndustries3 = Wind.WSS(symbols, fields, params)

    # 中信行业
    params["industryType"] = 3
    params["industryStandard"] = 1
    citicIndustries1 = Wind.WSS(symbols, fields, params)
    params["industryStandard"] = 2
    citicIndustries2 = Wind.WSS(symbols, fields, params)
    params["industryStandard"] = 3
    citicIndustries3 = Wind.WSS(symbols, fields, params)

    # ---上市日期 , 摘牌日期---
    info = Wind.WSS(symbols, ["ipo_date", "delist_date", "mkt", "sec_name"])

    # ---Save to DataBase---
    for i in range(len(symbols)):
        symbol = symbols[i]
        dataObject = {}
        dataObject["Symbol"] = symbol
        # dataObject["DateTime"] = sDatetime # for MongoDB
        # dataObject["StdDateTime"] = Gadget.ToUTCDateTime(datetime1) # for MongoDB
        if symbol[-2:] == "SZ":
            dataObject["Exchange"] = "SZE"
        else:
            dataObject["Exchange"] = "SSE"
        dataObject["Instrument_Type"] = "Stock"
        dataObject["Description"] = info[i]["sec_name"]
        dataObject["Raw_Code"] = symbol[:6]
        dataObject["Currency"] = "CNY"
        dataObject["Key2"] = symbol # for MongoDB
        dataObject["Market"] = info[i]["mkt"]
        ipoDate = info[i]["ipo_date"]
        ipoDate = Gadget.FilterWindDateTimeDirty(ipoDate)
        # dataObject["IPO_Date"] = Gadget.ToUTCDateTime(ipoDate) # no more UTC DateTime 2019-7-4
        dataObject["IPO_Date"] = ipoDate
        dataObject["DateTime1"] = dataObject["IPO_Date"]

        deListDate = info[i]["delist_date"]
        if deListDate > datetime(1900, 1, 1):
            deListDate = Gadget.FilterWindDateTimeDirty(deListDate)
            # dataObject["Delist_Date"] = Gadget.ToUTCDateTime(deListDate)
            dataObject["Delist_Date"] = deListDate
            dataObject["DateTime2"] = dataObject["Delist_Date"]
            # print("Delist " + symbol)
        else:
            maxDateTime = datetime(2100, 1, 1)
            # maxDateTime = Gadget.ToUTCDateTime(maxDateTime)
            dataObject["DateTime2"] = maxDateTime

        # properties = {}
        dataObject["Industry"] = citicIndustries1[i]["industry2"]
        dataObject["SW_Industry1"] = swIndustries1[i]["industry2"]
        dataObject["SW_Industry2"] = swIndustries2[i]["industry2"]
        dataObject["SW_Industry3"] = swIndustries3[i]["industry2"]
        dataObject["CS_Industry1"] = citicIndustries1[i]["industry2"]
        dataObject["CS_Industry2"] = citicIndustries2[i]["industry2"]
        dataObject["CS_Industry3"] = citicIndustries3[i]["industry2"]

        # dataObject["Properties"] = properties
        # dataObject["Values"] = {}

        # ---Add to DataBase---
        # database.insertIfNotExisted("Instruments","Stock",dataObject, {"Symbol":symbol})
        database.Upsert("financial_data", "instrument_stock", {"Symbol": symbol}, dataObject)

        # ---Add to Cache---
        # instrumentInTrading.append(dataObject)

        # update = {}
        # update["$set"] = dataObject
        # coll.update_one({"Symbol":symbol}, update, upsert=True)
        kkwood = 1


# 处理摘牌股票
def ProcessDelistedStock(database, delistSymbols):
    #
    delistDates = Wind.WSS(delistSymbols, "delist_date")
    for i in range(len(delistDates)):
        symbol = delistSymbols[i]

        # existed = instrumentsInDatabase.get(symbol)
        #
        # if existed != None and "Delist_Date" not in existed:

        deListDate = delistDates[i]["delist_date"]
        print("Found new Delist_Date " + symbol + " " + str(deListDate))
        minDate = datetime(1900, 1, 1)
        if deListDate < minDate:
            print("Unrecognized", deListDate)
            continue
        dataObject = {}
        dataObject["Delist_Date"] = Gadget.ToUTCDateTime(deListDate)
        dataObject["DateTime2"] = dataObject["Delist_Date"]
        dataObject["Key2"] = symbol
        print("Delist", symbol)
        database.Update("financial_data", "instrument_stock", {"Symbol": symbol}, dataObject)


# ---更新股票列表---
# ---不要更新已存在的，只添加新股票, 也更新摘牌日期---
def Download_Stock_List_Auto(database, realtime=None):

    datetime1 = datetime.now()
    datetime1 = Gadget.ToDate(datetime1)

    # ---Load Database---
    df_instruments_db = database.GetDataFrame("Instruments", "Stock", sort=[])
    df_delisted = df_instruments_db[df_instruments_db["datetime2"] < datetime(2100, 1, 1)]
    df_listed = df_instruments_db[df_instruments_db["datetime2"] >= datetime(2100, 1, 1)]
    listed_symbol_in_db = df_listed["symbol"].tolist()
    delisted_symbol_in_db = df_delisted["symbol"].tolist()
    symbol_in_db = df_instruments_db["symbol"].tolist()
    df_instruments_db.set_index("symbol", inplace=True)

    # ---Get All A-Stock List---
    # ---0列是时间日期，1列是Symbol，2列是中文名称---
    data, dt = Wind.WSet_Instruments(datetime1, sectorName="全部A股")
    if data == None or len(data) == 0:
        print("No Data, Can't Update Stock_List")
        return

    print("Total Listed Stocks @" + str(dt) + " # " + str(len(data)))
    to_add_new_symbols = []
    for d in data:
        symbol = d["Symbol"]
        name = d["Name"]
        if symbol in df_instruments_db.index: # 存在
            old_name = df_instruments_db.loc[symbol]["description"]
            if name != old_name:
                print("Stock Rename", symbol, old_name, "to", name)
                to_add_new_symbols.append(symbol)
        else: # 不存在于原数据库
            print("New Stock", symbol, name)
            to_add_new_symbols.append(symbol)

    # ---处理新股票 && 改名股票---
    if len(to_add_new_symbols) > 0:
        print(str(len(to_add_new_symbols)) + " Stocks needed to update")
        ProcessNewStock(database, to_add_new_symbols, datetime1)
    else:
        print("No more Stocks needed to update")

    # ---处理摘牌股票---
    to_update_delisted_state = []
    to_add_delisted = []
    data, dt = Wind.WSet_Instruments(datetime1, sectorName="已摘牌股票")
    for d in data:
        symbol = d["Symbol"]
        name = d["Name"]
        if symbol in delisted_symbol_in_db: # 数据库中已记录退市
            pass
        elif symbol in listed_symbol_in_db: # 数据库中未记录退市 -> 更新状态
            print("Update Delisted State", symbol, name)
            to_update_delisted_state.append(symbol)
        else: # 未出现在数据库中
            print("Found New Delisted", symbol, name)
            to_add_delisted.append(symbol)

    #
    if len(to_update_delisted_state) > 0: # 更新状态
        ProcessDelistedStock(database, to_update_delisted_state)
    #
    if len(to_add_delisted) > 0: # 未入库的退市股票
        ProcessNewStock(database, to_add_delisted, datetime1)

    #
    print("Finish to Update Stock List")


# ---冷启动，全面读取，全面刷新---
def Download_Stock_List(database, realtime=None):
    #
    datetime1 = datetime.now()
    datetime1 = Gadget.ToDate(datetime1)

    # ---Load Database---
    df_instruments_db = database.GetDataFrame("financial_data", "instrument_stock", sort=[])
    df_delisted = df_instruments_db[df_instruments_db["datetime2"] < datetime(2100, 1, 1)]
    df_listed = df_instruments_db[df_instruments_db["datetime2"] >= datetime(2100, 1, 1)]
    listed_symbol_in_db = df_listed["symbol"].tolist()
    delisted_symbol_in_db = df_delisted["symbol"].tolist()
    df_instruments_db.set_index("symbol", inplace=True)

    print("Total Stock in DB", len(df_instruments_db))
    print("Listed in DB", len(df_listed))
    print("DeListed in DB", len(df_delisted))

    # ---Get All A-Stock List---
    # ---0列是时间日期，1列是Symbol，2列是中文名称---
    data, dt = Wind.WSet_Instruments(datetime1, sectorName="全部A股")
    if data == None or len(data) == 0:
        print("No Data, Can't Update Stock_List")
        return

    print("Total Listed Stocks @" + str(dt) + " # " + str(len(data)))
    to_add_new_symbols = []
    for d in data:
        symbol = d["Symbol"]
        name = d["Name"]
        if symbol not in delisted_symbol_in_db:
            to_add_new_symbols.append(symbol)

    ProcessNewStock(database, to_add_new_symbols, datetime1)
    #
    print("Finish to Update Stock List")


if __name__ == '__main__':
    from Core.Config import *
    pathfilename = os.getcwd() + "\..\Config\config2.json"
    #
    config = Config(pathfilename)
    database = config.DataBase("JDMySQL")
    realtime = config.RealTime()
    realtime = None
    #
    Wind.w.start()
    Download_Stock_List(database, realtime=None)